package cn.com.bsoft.mobile.service

import cn.com.bsoft.mobile.dao.MobileDeviceDao
import cn.com.bsoft.mobile.dao.MobileUserDao
import cn.com.bsoft.mobile.dao.UserAppRelationshipDao
import cn.com.bsoft.mobile.entity.MobileApp
import cn.com.bsoft.mobile.entity.MobileDevice
import cn.com.bsoft.mobile.entity.MobileUser
import cn.com.bsoft.mobile.entity.MobileUserAppDeviceRelationship
import cn.com.bsoft.mobile.model.Device
import cn.com.bsoft.mobile.model.DeviceType
import cn.com.bsoft.mobile.model.LinkUserAppDeviceReq
import cn.com.bsoft.mobile.model.RemoveUserAppDeviceReq
import cn.net.xyan.blossom.kotlin.AllOpen
import cn.net.xyan.blossom.kotlin.StatusAndMessageError
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.transaction.annotation.Transactional

interface MobileDeviceService{
    fun deviceType(type:String):DeviceType
    fun link(req: LinkUserAppDeviceReq):MobileUserAppDeviceRelationship
    fun remove(req:RemoveUserAppDeviceReq):MobileUserAppDeviceRelationship

    fun codeForNotifyPush(user:MobileUser,app:MobileApp,device:MobileDevice):String?
    fun saveDevice(device:Device):MobileDevice
    fun findByUser(user:MobileUser,app:MobileApp):List<MobileDevice>
}

@AllOpen
class DefaultMobileDeviceService:MobileDeviceService{



    @Autowired
    lateinit var userDao:MobileUserDao

    @Autowired
    lateinit var deviceDao:MobileDeviceDao

    @Autowired
    lateinit var relationshipDao: UserAppRelationshipDao

    @Autowired
    lateinit var appService:MobileAppService

    override fun deviceType(type: String): DeviceType {
        return when(type){
            DeviceType.Android.value -> DeviceType.Android
            DeviceType.iOS.value -> DeviceType.iOS
            DeviceType.WindowsPhone.value -> DeviceType.WindowsPhone
            else -> throw StatusAndMessageError("unknown device:$type")
        }
    }

    override fun codeForNotifyPush(user: MobileUser, app: MobileApp, device: MobileDevice): String? {
        return relationshipDao.findByUserAndAppAndDevice(user,app,device)?.codeForNotifyPush
    }

    @Transactional
    override fun link(req: LinkUserAppDeviceReq):MobileUserAppDeviceRelationship {
        val user = userDao.findOne(req.username)
        var app = appService.queryApp(req.device.type,req.appID)
        var device = saveDevice(req.device)

        var relationship = relationshipDao.findByUserAndAppAndDevice(user,app!!,device)

        if (relationship == null){
            relationship = MobileUserAppDeviceRelationship()

            relationship.app = app
            relationship.device = device


        }

        relationship.user = user
        relationship.codeForNotifyPush = req.codeForNotiyPush

        relationship = relationshipDao.saveAndFlush(relationship)
        return relationship!!

    }

    @Transactional
    override fun remove(req: RemoveUserAppDeviceReq):MobileUserAppDeviceRelationship {
        val user = userDao.findOne(req.username)
        var app = appService.queryApp(req.device.type,req.appID)
        var device = saveDevice(req.device)

        var relationship: MobileUserAppDeviceRelationship =
                relationshipDao.findByUserAndAppAndDevice(user,app!!,device) ?: throw StatusAndMessageError("用户 ${req.username} 尚未绑定 app:${req.appID}")


        relationshipDao.delete(relationship)

        return relationship

    }

    @Transactional
    override fun saveDevice(device: Device): MobileDevice {
        var mobileDevice = MobileDevice(device.udid,device.type.value)

        mobileDevice.model = device.model
        mobileDevice.vendor = device.vendor
        mobileDevice.osName = device.osName

        return deviceDao.saveAndFlush(mobileDevice)
    }

    override fun findByUser(user: MobileUser,app:MobileApp): List<MobileDevice> {
        return relationshipDao.findByUserAndApp(user,app).filter { it.device!=null }.map {
            it.device!!
        }
    }

}